<template>
  <div class="avatar-container">
    <el-dialog draggable :title="_props.title" v-model="dialogVisibleCorpper" width="800px">
      <el-row :gutter="20">
        <el-col :span="12">
          <vue-cropper ref="cropperRef" v-bind="options" @realTime="handleRealTime" class="cropper" />
        </el-col>
        <el-col :span="12" class="preview-col">
          <div class="preview-container">
            <div :style="previews.div">
              <img :src="previews.url" :style="previews.img" />
            </div>
          </div>
        </el-col>
      </el-row>
      <el-row class="controls-row">
        <el-col :span="4">
          <el-upload action="#" :http-request="() => {}" :before-upload="beforeUpload" :show-file-list="false">
            <el-button>选择图片</el-button>
          </el-upload>
        </el-col>
        <el-col :span="2">
          <el-button icon="Plus" @click="changeScale(1)"></el-button>
        </el-col>
        <el-col :span="2">
          <el-button icon="Minus" @click="changeScale(-1)"></el-button>
        </el-col>
        <el-col :span="2">
          <el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
        </el-col>
        <el-col :span="2">
          <el-button icon="RefreshRight" @click="rotateRight()"></el-button>
        </el-col>
        <el-col :span="12"></el-col>
      </el-row>
      <el-row class="submit-col">
        <el-button type="primary" @click="determine()"> 提 交 </el-button>
      </el-row>
    </el-dialog>
  </div>
</template>

<script setup name="Cropper">
  import { reactive, ref } from 'vue';
  import { VueCropper } from 'vue-cropper';
  import 'vue-cropper/dist/index.css';

  // VueCropper 组件的参数
  const options = reactive({
    img: '', // 默认图片地址
    autoCrop: true, // 是否默认生成截图框
    autoCropWidth: 200, // 默认生成截图框宽度
    autoCropHeight: 200, // 默认生成截图框高度
    fixedBox: true, // 固定截图框大小 不允许改变
    maxImgSize: 200, // 限制图片最大高度
    limitMinSize: [50, 50], // 限制图片最小高度和宽度
    fixed: false, // 固定截图框宽高比例
    fixedNumber: [2, 1], // 固定比例
    fillCover: '', // 默认填充颜色
  });

  // 图片预览
  let previews = ref({
    w: 200,
    h: 200,
    url: '',
    div: '',
    img: '',
  });

  const cropperRef = ref();
  const _props = defineProps({
    title: {
      type: String,
      default: '上传图片',
    },
  });

  const emit = defineEmits(['confirm']);

  let dialogVisibleCorpper = ref(false);

  // 实时更新预览
  const handleRealTime = (data) => {
    previews.value = data;
  };

  /** 打开弹框 */
  const open = () => {
    dialogVisibleCorpper.value = true;
  };

  /** 修改图片大小 正数为变大 负数变小 */
  const changeScale = (num) => {
    num = num || 1;
    cropperRef.value.changeScale(num);
  };

  /** 向左边旋转90度 */
  const rotateLeft = () => {
    cropperRef.value.rotateLeft();
  };

  /** 向右边旋转90度 */
  const rotateRight = () => {
    cropperRef.value.rotateRight();
  };

  /** 上传图片处理  */
  const beforeUpload = (rawFile) => {
    if (rawFile.type.indexOf('image/') == -1) {
      ElMessage.error('请上传图片类型文件!');
      return false;
    }
    if (rawFile.size / 1024 / 1024 > 1) {
      ElMessage.error('文件大小不能超过2MB!');
      return false;
    }
    const reader = new FileReader();
    reader.readAsDataURL(rawFile);
    reader.onload = () => {
      // 图片在这里
      options.img = reader.result;
    };
  };

  /** 提交图片 */
  const determine = () => {
    cropperRef.value.getCropBlob((blob) => {
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = () => {
        emit('confirm', reader.result);
        dialogVisibleCorpper.value = false;
      };
    });
  };

  defineExpose({
    open,
  });
</script>

<style lang="scss" scoped>
  .cropper {
    height: 300px;
  }

  .preview-col {
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .preview-container {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    border: 1px dashed #5c6c78;
    overflow: hidden;
    margin: 5px;
  }

  .controls-row {
    margin-top: 12px;
  }

  .submit-col {
    margin-top: 12px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
</style>
